﻿using ArchiSimple.Windows.Model;
using ArchiSimple.Windows.ViewModel;
using ArchiSimple.Windows.ViewModel.PlanObjects;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Xunit;

namespace ArchiSimple.Windows.Test.ViewModel
{
    public class PlanViewModelTest_AddWall
    {
        [Fact]
        public void CutWall()
        {
            using (new LocatorContext())
            {
                var viewModel = Locator.Locate<PlanViewModel>(null);
                viewModel.Init();
                viewModel.LoadPlanMessage(new Message.LoadPlanMessage { Plan = new Plan() });

                viewModel.AddWall(0, 0, 100, 100);

                Assert.Equal(3, viewModel.PlanObjects.Count);
                Assert.IsType(typeof(WallViewModel), viewModel.PlanObjects[0]);
                Assert.IsType(typeof(PointViewModel), viewModel.PlanObjects[1]);
                Assert.IsType(typeof(PointViewModel), viewModel.PlanObjects[2]);

                viewModel.AddWall(50, 50, 0, 100);

                Assert.Equal(7, viewModel.PlanObjects.Count);
                Assert.IsType(typeof(WallViewModel), viewModel.PlanObjects[0]);
                Assert.IsType(typeof(PointViewModel), viewModel.PlanObjects[1]);
                Assert.IsType(typeof(PointViewModel), viewModel.PlanObjects[2]);
                Assert.IsType(typeof(WallViewModel), viewModel.PlanObjects[3]);
                Assert.IsType(typeof(PointViewModel), viewModel.PlanObjects[4]);
                Assert.IsType(typeof(WallViewModel), viewModel.PlanObjects[5]);
                Assert.IsType(typeof(PointViewModel), viewModel.PlanObjects[6]);

                var wall1 = viewModel.PlanObjects[0] as WallViewModel;
                var wall2 = viewModel.PlanObjects[3] as WallViewModel;
                var wall3 = viewModel.PlanObjects[5] as WallViewModel;

                Assert.Equal(0, wall1.Begin.X);
                Assert.Equal(0, wall1.Begin.Y);
                Assert.Equal(50, wall1.End.X);
                Assert.Equal(50, wall1.End.Y);
                Assert.Equal(50, wall2.Begin.X);
                Assert.Equal(50, wall2.Begin.Y);
                Assert.Equal(0, wall2.End.X);
                Assert.Equal(100, wall2.End.Y);
                Assert.Equal(50, wall3.Begin.X);
                Assert.Equal(50, wall3.Begin.Y);
                Assert.Equal(100, wall3.End.X);
                Assert.Equal(100, wall3.End.Y);

                Assert.Same(wall1.End, wall2.Begin);
                Assert.Same(wall1.End, wall3.Begin);
            }
        }

        [Fact]
        public void CutWall_Invert()
        {
            using (new LocatorContext())
            {
                var viewModel = Locator.Locate<PlanViewModel>(null);
                viewModel.Init();
                viewModel.LoadPlanMessage(new Message.LoadPlanMessage { Plan = new Plan() });

                viewModel.AddWall(0, 0, 100, 100);

                Assert.Equal(3, viewModel.PlanObjects.Count);
                Assert.IsType(typeof(WallViewModel), viewModel.PlanObjects[0]);
                Assert.IsType(typeof(PointViewModel), viewModel.PlanObjects[1]);
                Assert.IsType(typeof(PointViewModel), viewModel.PlanObjects[2]);

                viewModel.AddWall(0, 100, 50, 50);

                Assert.Equal(7, viewModel.PlanObjects.Count);
                Assert.IsType(typeof(WallViewModel), viewModel.PlanObjects[0]);
                Assert.IsType(typeof(PointViewModel), viewModel.PlanObjects[1]);
                Assert.IsType(typeof(PointViewModel), viewModel.PlanObjects[2]);
                Assert.IsType(typeof(WallViewModel), viewModel.PlanObjects[3]);
                Assert.IsType(typeof(PointViewModel), viewModel.PlanObjects[4]);
                Assert.IsType(typeof(PointViewModel), viewModel.PlanObjects[5]);
                Assert.IsType(typeof(WallViewModel), viewModel.PlanObjects[6]);

                var wall1 = viewModel.PlanObjects[0] as WallViewModel;
                var wall2 = viewModel.PlanObjects[3] as WallViewModel;
                var wall3 = viewModel.PlanObjects[6] as WallViewModel;

                Assert.Equal(0, wall1.Begin.X);
                Assert.Equal(0, wall1.Begin.Y);
                Assert.Equal(50, wall1.End.X);
                Assert.Equal(50, wall1.End.Y);
                Assert.Equal(0, wall2.Begin.X);
                Assert.Equal(100, wall2.Begin.Y);
                Assert.Equal(50, wall2.End.X);
                Assert.Equal(50, wall2.End.Y);
                Assert.Equal(50, wall3.Begin.X);
                Assert.Equal(50, wall3.Begin.Y);
                Assert.Equal(100, wall3.End.X);
                Assert.Equal(100, wall3.End.Y);

                Assert.Same(wall1.End, wall2.End);
                Assert.Same(wall1.End, wall3.Begin);
            }
        }

        [Fact]
        public void CutWallButNoNewRoom()
        {
            using (new LocatorContext())
            {
                var p1 = new Point { X = 0, Y = 0 };
                var p2 = new Point { X = 100, Y = 0 };
                var p3 = new Point { X = 100, Y = 100 };
                var p4 = new Point { X = 0, Y = 100 };
                var p5 = new Point { X = 100, Y = 50 };
                var p6 = new Point { X = 200, Y = 50 };

                var viewModel = Locator.Locate<PlanViewModel>(null);
                viewModel.Init();
                viewModel.LoadPlanMessage(new Message.LoadPlanMessage { Plan = new Plan() });

                viewModel.AddWall(p1.X, p1.Y, p2.X, p2.Y);
                viewModel.AddWall(p2.X, p2.Y, p3.X, p3.Y);
                viewModel.AddWall(p3.X, p3.Y, p4.X, p4.Y);
                viewModel.AddWall(p4.X, p4.Y, p1.X, p1.Y);

                Assert.Equal(4, viewModel.PlanObjects.OfType<PointViewModel>().Count());
                Assert.Equal(4, viewModel.PlanObjects.OfType<WallViewModel>().Count());
                Assert.Equal(1, viewModel.PlanObjects.OfType<RoomViewModel>().Count());

                var room = viewModel.PlanObjects.OfType<RoomViewModel>().First();

                Assert.Equal(4, room.Points.Count());
                Assert.Equal(p4.X, room.Points[0].X);
                Assert.Equal(p4.Y, room.Points[0].Y);
                Assert.Equal(p3.X, room.Points[1].X);
                Assert.Equal(p3.Y, room.Points[1].Y);
                Assert.Equal(p2.X, room.Points[2].X);
                Assert.Equal(p2.Y, room.Points[2].Y);
                Assert.Equal(p1.X, room.Points[3].X);
                Assert.Equal(p1.Y, room.Points[3].Y);

                viewModel.AddWall(p5.X, p5.Y, p6.X, p6.Y);

                Assert.Equal(6, viewModel.PlanObjects.OfType<PointViewModel>().Count());
                Assert.Equal(6, viewModel.PlanObjects.OfType<WallViewModel>().Count());
                Assert.Equal(1, viewModel.PlanObjects.OfType<RoomViewModel>().Count());

                Assert.Equal(5, room.Points.Count());
                Assert.Equal(p4.X, room.Points[0].X);
                Assert.Equal(p4.Y, room.Points[0].Y);
                Assert.Equal(p3.X, room.Points[1].X);
                Assert.Equal(p3.Y, room.Points[1].Y);
                Assert.Equal(p5.X, room.Points[2].X);
                Assert.Equal(p5.Y, room.Points[2].Y);
                Assert.Equal(p2.X, room.Points[3].X);
                Assert.Equal(p2.Y, room.Points[3].Y);
                Assert.Equal(p1.X, room.Points[4].X);
                Assert.Equal(p1.Y, room.Points[4].Y);

                Assert.NotNull(viewModel.WallGeometry);
            }
        }

        [Fact]
        public void CutWallButNoNewRoomOnLastWall()
        {
            using (new LocatorContext())
            {
                var p1 = new Point { X = 0, Y = 0 };
                var p2 = new Point { X = 100, Y = 0 };
                var p3 = new Point { X = 100, Y = 100 };
                var p4 = new Point { X = 0, Y = 100 };
                var p5 = new Point { X = 0, Y = 50 };
                var p6 = new Point { X = -100, Y = 50 };

                var viewModel = Locator.Locate<PlanViewModel>(null);
                viewModel.Init();
                viewModel.LoadPlanMessage(new Message.LoadPlanMessage { Plan = new Plan() });

                viewModel.AddWall(p1.X, p1.Y, p2.X, p2.Y);
                viewModel.AddWall(p2.X, p2.Y, p3.X, p3.Y);
                viewModel.AddWall(p3.X, p3.Y, p4.X, p4.Y);
                viewModel.AddWall(p4.X, p4.Y, p1.X, p1.Y);

                Assert.Equal(4, viewModel.PlanObjects.OfType<PointViewModel>().Count());
                Assert.Equal(4, viewModel.PlanObjects.OfType<WallViewModel>().Count());
                Assert.Equal(1, viewModel.PlanObjects.OfType<RoomViewModel>().Count());

                var room = viewModel.PlanObjects.OfType<RoomViewModel>().First();

                Assert.Equal(4, room.Points.Count());
                Assert.Equal(p4.X, room.Points[0].X);
                Assert.Equal(p4.Y, room.Points[0].Y);
                Assert.Equal(p3.X, room.Points[1].X);
                Assert.Equal(p3.Y, room.Points[1].Y);
                Assert.Equal(p2.X, room.Points[2].X);
                Assert.Equal(p2.Y, room.Points[2].Y);
                Assert.Equal(p1.X, room.Points[3].X);
                Assert.Equal(p1.Y, room.Points[3].Y);

                viewModel.AddWall(p5.X, p5.Y, p6.X, p6.Y);

                Assert.Equal(6, viewModel.PlanObjects.OfType<PointViewModel>().Count());
                Assert.Equal(6, viewModel.PlanObjects.OfType<WallViewModel>().Count());
                Assert.Equal(1, viewModel.PlanObjects.OfType<RoomViewModel>().Count());

                Assert.Equal(5, room.Points.Count());
                Assert.Equal(p4.X, room.Points[0].X);
                Assert.Equal(p4.Y, room.Points[0].Y);
                Assert.Equal(p3.X, room.Points[1].X);
                Assert.Equal(p3.Y, room.Points[1].Y);
                Assert.Equal(p2.X, room.Points[2].X);
                Assert.Equal(p2.Y, room.Points[2].Y);
                Assert.Equal(p1.X, room.Points[3].X);
                Assert.Equal(p1.Y, room.Points[3].Y);
                Assert.Equal(p5.X, room.Points[4].X);
                Assert.Equal(p5.Y, room.Points[4].Y);

                Assert.NotNull(viewModel.WallGeometry);
            }
        }

        [Fact]
        public void CutWallAndCreateRoom()
        {
            using (new LocatorContext())
            {
                var p1 = new Point { X = 0, Y = 0 };
                var p2 = new Point { X = 100, Y = 0 };
                var p3 = new Point { X = 100, Y = 100 };
                var p4 = new Point { X = 0, Y = 100 };
                var p5 = new Point { X = 0, Y = 50 };
                var p6 = new Point { X = 100, Y = 50 };

                var viewModel = Locator.Locate<PlanViewModel>(null);
                viewModel.Init();
                viewModel.LoadPlanMessage(new Message.LoadPlanMessage { Plan = new Plan() });

                viewModel.AddWall(p1.X, p1.Y, p2.X, p2.Y);
                viewModel.AddWall(p2.X, p2.Y, p3.X, p3.Y);
                viewModel.AddWall(p3.X, p3.Y, p4.X, p4.Y);
                viewModel.AddWall(p4.X, p4.Y, p1.X, p1.Y);

                Assert.Equal(4, viewModel.PlanObjects.OfType<PointViewModel>().Count());
                Assert.Equal(4, viewModel.PlanObjects.OfType<WallViewModel>().Count());
                Assert.Equal(1, viewModel.PlanObjects.OfType<RoomViewModel>().Count());

                viewModel.AddWall(p5.X, p5.Y, p6.X, p6.Y);

                Assert.Equal(6, viewModel.PlanObjects.OfType<PointViewModel>().Count());
                Assert.Equal(7, viewModel.PlanObjects.OfType<WallViewModel>().Count());
                Assert.Equal(2, viewModel.PlanObjects.OfType<RoomViewModel>().Count());

                Assert.NotNull(viewModel.WallGeometry);
            }
        }

        [Fact]
        public void WithJonction()
        {
            using (new LocatorContext())
            {
                var viewModel = Locator.Locate<PlanViewModel>(null);
                viewModel.Init();
                viewModel.LoadPlanMessage(new Message.LoadPlanMessage { Plan = new Plan() });

                viewModel.AddWallCommand.Execute(null);

                // Add begin point.
                viewModel.MousePoint = new System.Windows.Point(150, 100);
                viewModel.UpPlanCommand.Execute(null);

                // Cursor move.
                viewModel.MousePoint = new System.Windows.Point(153, 200);
                viewModel.PreviewWallCommand.Execute(null);

                // Add end point.
                viewModel.UpPlanCommand.Execute(null);

                Assert.Equal(3, viewModel.PlanObjects.Count);
                Assert.IsType(typeof(WallViewModel), viewModel.PlanObjects[0]);
                Assert.IsType(typeof(PointViewModel), viewModel.PlanObjects[1]);
                Assert.IsType(typeof(PointViewModel), viewModel.PlanObjects[2]);

                var beginPoint = viewModel.PlanObjects[1] as PointViewModel;
                Assert.Equal(150, beginPoint.X);
                Assert.Equal(150, beginPoint.Current.X);
                Assert.Equal(100, beginPoint.Y);
                Assert.Equal(100, beginPoint.Current.Y);

                var endPoint = viewModel.PlanObjects[2] as PointViewModel;
                Assert.Equal(150, endPoint.X);
                Assert.Equal(150, endPoint.Current.X);
                Assert.Equal(200, endPoint.Y);
                Assert.Equal(200, endPoint.Current.Y);

                var wall = viewModel.PlanObjects[0] as WallViewModel;
                Assert.Equal(beginPoint, wall.Begin);
                Assert.Equal(endPoint, wall.End);

                // Add Second line
                viewModel.AddWallCommand.Execute(null);

                // Add begin point.
                viewModel.MousePoint = new System.Windows.Point(150, 100);
                viewModel.UpPlanCommand.Execute(null);

                // Cursor move.
                viewModel.MousePoint = new System.Windows.Point(200, 103);
                viewModel.PreviewWallCommand.Execute(null);

                // Add end point.
                viewModel.UpPlanCommand.Execute(null);

                Assert.Equal(5, viewModel.PlanObjects.Count);
                Assert.IsType(typeof(WallViewModel), viewModel.PlanObjects[3]);
                Assert.IsType(typeof(PointViewModel), viewModel.PlanObjects[4]);

                var endPoint2 = viewModel.PlanObjects[4] as PointViewModel;
                Assert.Equal(200, endPoint2.X);
                Assert.Equal(200, endPoint2.Current.X);
                Assert.Equal(100, endPoint2.Y);
                Assert.Equal(100, endPoint2.Current.Y);

                var wall2 = viewModel.PlanObjects[3] as WallViewModel;
                Assert.Equal(endPoint2, wall2.End);

                // The two instance must to be the same. Two wall with one jonction point.
                Assert.Same(wall.Begin, wall2.Begin);
            }
        }

        /// <summary>
        /// Test if the snap works with a point who has move.
        /// </summary>
        [Fact]
        public void WithMovePoint()
        {
            using (new LocatorContext())
            {
                var viewModel = Locator.Locate<PlanViewModel>(null);
                viewModel.Init();
                viewModel.LoadPlanMessage(new Message.LoadPlanMessage { Plan = new Plan() });

                viewModel.AddWall(100, 100, 200, 200);

                var endPoint = viewModel.PlanObjects[2] as PointViewModel;

                Assert.Equal(200, endPoint.Current.X);
                Assert.Equal(200, endPoint.Current.Y);

                viewModel.MovePoint(endPoint, 300, 300);

                viewModel.AddWall(300, 300, 400, 400);

                Assert.Equal(5, viewModel.PlanObjects.Count);
                Assert.IsType(typeof(WallViewModel), viewModel.PlanObjects[0]);
                Assert.IsType(typeof(PointViewModel), viewModel.PlanObjects[1]);
                Assert.IsType(typeof(PointViewModel), viewModel.PlanObjects[2]);
                Assert.IsType(typeof(WallViewModel), viewModel.PlanObjects[3]);
                Assert.IsType(typeof(PointViewModel), viewModel.PlanObjects[4]);
            }
        }

        [Fact]
        public void WithNoMove()
        {
            using (new LocatorContext())
            {
                var viewModel = Locator.Locate<PlanViewModel>(null);
                viewModel.Init();
                viewModel.LoadPlanMessage(new Message.LoadPlanMessage { Plan = new Plan() });


                viewModel.AddWallCommand.Execute(null);

                // Add begin point.
                viewModel.MousePoint = new System.Windows.Point(100, 100);
                viewModel.UpPlanCommand.Execute(null);

                // Add end point.
                viewModel.UpPlanCommand.Execute(null);

                Assert.Equal(0, viewModel.PlanObjects.Count);
            }
        }

        [Fact]
        public void WithMoveButSamePoint()
        {
            using (new LocatorContext())
            {
                var viewModel = Locator.Locate<PlanViewModel>(null);
                viewModel.Init();
                viewModel.LoadPlanMessage(new Message.LoadPlanMessage { Plan = new Plan() });

                viewModel.AddWall(100, 100, 100, 100);

                Assert.Equal(0, viewModel.PlanObjects.Count);
            }
        }

        /// <summary>
        /// Test the no delete point of the plan.
        /// </summary>
        [Fact]
        public void WithNoMoveAndJonction()
        {
            using (new LocatorContext())
            {
                var viewModel = Locator.Locate<PlanViewModel>(null);
                viewModel.Init();
                viewModel.LoadPlanMessage(new Message.LoadPlanMessage { Plan = new Plan() });

                viewModel.AddWall(0, 0, 100, 100);

                viewModel.AddWallCommand.Execute(null);

                // Add begin point.
                viewModel.MousePoint = new System.Windows.Point(100, 100);
                viewModel.UpPlanCommand.Execute(null);

                // Add end point.
                viewModel.UpPlanCommand.Execute(null);

                Assert.Equal(3, viewModel.PlanObjects.Count);
                Assert.IsType(typeof(WallViewModel), viewModel.PlanObjects[0]);
                Assert.IsType(typeof(PointViewModel), viewModel.PlanObjects[1]);
                Assert.IsType(typeof(PointViewModel), viewModel.PlanObjects[2]);
                Assert.Equal(0, (viewModel.PlanObjects[1] as PointViewModel).X);
                Assert.Equal(100, (viewModel.PlanObjects[2] as PointViewModel).X);
            }
        }

        [Fact]
        public void RoomWithCut()
        {
            using (new LocatorContext())
            {
                var p1 = new Point { X = 0, Y = 0 };
                var p2 = new Point { X = 100, Y = 0 };
                var p3 = new Point { X = 200, Y = 0 };
                var p4 = new Point { X = 200, Y = 100 };
                var p5 = new Point { X = 100, Y = 100 };
                var p6 = new Point { X = 0, Y = 100 };

                var viewModel = Locator.Locate<PlanViewModel>(null);
                viewModel.Init();
                viewModel.LoadPlanMessage(new Message.LoadPlanMessage { Plan = new Plan() });

                viewModel.AddWall(p1.X, p1.Y, p2.X, p2.Y);
                viewModel.AddWall(p2.X, p2.Y, p3.X, p3.Y);
                viewModel.AddWall(p3.X, p3.Y, p4.X, p4.Y);
                viewModel.AddWall(p4.X, p4.Y, p5.X, p5.Y);
                viewModel.AddWall(p5.X, p5.Y, p6.X, p6.Y);
                viewModel.AddWall(p6.X, p6.Y, p1.X, p1.Y);

                Assert.Equal(1, viewModel.PlanObjects.OfType<RoomViewModel>().Count());

                // Cut in middle.
                viewModel.AddWall(p2.X, p2.Y, p5.X, p5.Y);

                Assert.Equal(2, viewModel.PlanObjects.OfType<RoomViewModel>().Count());

                // Cut the seconde room.
                viewModel.AddWall(p4.X, p4.Y, p2.X, p2.Y);

                Assert.Equal(3, viewModel.PlanObjects.OfType<RoomViewModel>().Count());
            }
        }

        [Fact]
        public void RoomWithCut2()
        {
            using (new LocatorContext())
            {
                var p1 = new Point { X = 0, Y = 0 };
                var p2 = new Point { X = 100, Y = 0 };
                var p3 = new Point { X = 200, Y = 0 };
                var p4 = new Point { X = 200, Y = 100 };
                var p5 = new Point { X = 100, Y = 100 };
                var p6 = new Point { X = 0, Y = 100 };

                var viewModel = Locator.Locate<PlanViewModel>(null);
                viewModel.Init();
                viewModel.LoadPlanMessage(new Message.LoadPlanMessage { Plan = new Plan() });

                viewModel.AddWall(p1.X, p1.Y, p2.X, p2.Y);
                viewModel.AddWall(p2.X, p2.Y, p3.X, p3.Y);
                viewModel.AddWall(p3.X, p3.Y, p4.X, p4.Y);
                viewModel.AddWall(p4.X, p4.Y, p5.X, p5.Y);
                viewModel.AddWall(p5.X, p5.Y, p6.X, p6.Y);
                viewModel.AddWall(p6.X, p6.Y, p1.X, p1.Y);

                Assert.Equal(1, viewModel.PlanObjects.OfType<RoomViewModel>().Count());

                // Cut in middle.
                viewModel.AddWall(p2.X, p2.Y, p5.X, p5.Y);

                Assert.Equal(2, viewModel.PlanObjects.OfType<RoomViewModel>().Count());

                // Cut the seconde room.
                viewModel.AddWall(p2.X, p2.Y, p4.X, p4.Y);

                Assert.Equal(3, viewModel.PlanObjects.OfType<RoomViewModel>().Count());
            }
        }

        [Fact]
        public void Room()
        {
            using (new LocatorContext())
            {
                var p1 = new Point { X = 150, Y = 100 };
                var p2 = new Point { X = 200, Y = 200 };
                var p3 = new Point { X = 300, Y = 450 };
                var p4 = new Point { X = 410, Y = 300 };
                var p5 = new Point { X = 150, Y = 200 };

                var viewModel = Locator.Locate<PlanViewModel>(null);
                viewModel.Init();
                viewModel.LoadPlanMessage(new Message.LoadPlanMessage { Plan = new Plan() });

                viewModel.AddWall(p1.X, p1.Y, p2.X, p2.Y);

                Assert.Equal(3, viewModel.PlanObjects.Count);
                Assert.IsType(typeof(WallViewModel), viewModel.PlanObjects[0]);
                Assert.IsType(typeof(PointViewModel), viewModel.PlanObjects[1]);
                Assert.Equal(1, (viewModel.PlanObjects[0] as WallViewModel).Begin.NextPoints.Count);
                Assert.Equal(1, (viewModel.PlanObjects[0] as WallViewModel).End.NextPoints.Count);
                Assert.IsType(typeof(PointViewModel), viewModel.PlanObjects[2]);

                viewModel.AddWall(p1.X, p1.Y, p3.X, p3.Y);

                Assert.Equal(5, viewModel.PlanObjects.Count);
                Assert.IsType(typeof(WallViewModel), viewModel.PlanObjects[3]);
                Assert.Equal(2, (viewModel.PlanObjects[0] as WallViewModel).Begin.NextPoints.Count);
                Assert.Equal(1, (viewModel.PlanObjects[0] as WallViewModel).End.NextPoints.Count);
                Assert.Equal(2, (viewModel.PlanObjects[3] as WallViewModel).Begin.NextPoints.Count);
                Assert.Equal(1, (viewModel.PlanObjects[3] as WallViewModel).End.NextPoints.Count);
                Assert.IsType(typeof(PointViewModel), viewModel.PlanObjects[4]);

                viewModel.AddWall(p3.X, p3.Y, p4.X, p4.Y);

                Assert.Equal(7, viewModel.PlanObjects.Count);
                Assert.IsType(typeof(WallViewModel), viewModel.PlanObjects[5]);
                Assert.Equal(2, (viewModel.PlanObjects[0] as WallViewModel).Begin.NextPoints.Count);
                Assert.Equal(1, (viewModel.PlanObjects[0] as WallViewModel).End.NextPoints.Count);
                Assert.Equal(2, (viewModel.PlanObjects[3] as WallViewModel).Begin.NextPoints.Count);
                Assert.Equal(2, (viewModel.PlanObjects[3] as WallViewModel).End.NextPoints.Count);
                Assert.Equal(2, (viewModel.PlanObjects[5] as WallViewModel).Begin.NextPoints.Count);
                Assert.Equal(1, (viewModel.PlanObjects[5] as WallViewModel).End.NextPoints.Count);
                Assert.IsType(typeof(PointViewModel), viewModel.PlanObjects[6]);

                viewModel.AddWall(p4.X, p4.Y, p5.X, p5.Y);

                Assert.Equal(9, viewModel.PlanObjects.Count);
                Assert.IsType(typeof(WallViewModel), viewModel.PlanObjects[7]);
                Assert.Equal(2, (viewModel.PlanObjects[0] as WallViewModel).Begin.NextPoints.Count);
                Assert.Equal(1, (viewModel.PlanObjects[0] as WallViewModel).End.NextPoints.Count);
                Assert.Equal(2, (viewModel.PlanObjects[3] as WallViewModel).Begin.NextPoints.Count);
                Assert.Equal(2, (viewModel.PlanObjects[3] as WallViewModel).End.NextPoints.Count);
                Assert.Equal(2, (viewModel.PlanObjects[5] as WallViewModel).Begin.NextPoints.Count);
                Assert.Equal(2, (viewModel.PlanObjects[5] as WallViewModel).End.NextPoints.Count);
                Assert.Equal(2, (viewModel.PlanObjects[7] as WallViewModel).Begin.NextPoints.Count);
                Assert.Equal(1, (viewModel.PlanObjects[7] as WallViewModel).End.NextPoints.Count);
                Assert.IsType(typeof(PointViewModel), viewModel.PlanObjects[8]);

                viewModel.AddWall(p2.X, p2.Y, p5.X, p5.Y);

                Assert.Equal(11, viewModel.PlanObjects.Count);
                Assert.IsType(typeof(WallViewModel), viewModel.PlanObjects[9]);
                Assert.Equal(2, (viewModel.PlanObjects[0] as WallViewModel).Begin.NextPoints.Count);
                Assert.Equal(2, (viewModel.PlanObjects[0] as WallViewModel).End.NextPoints.Count);
                Assert.Equal(2, (viewModel.PlanObjects[3] as WallViewModel).Begin.NextPoints.Count);
                Assert.Equal(2, (viewModel.PlanObjects[3] as WallViewModel).End.NextPoints.Count);
                Assert.Equal(2, (viewModel.PlanObjects[5] as WallViewModel).Begin.NextPoints.Count);
                Assert.Equal(2, (viewModel.PlanObjects[5] as WallViewModel).End.NextPoints.Count);
                Assert.Equal(2, (viewModel.PlanObjects[7] as WallViewModel).Begin.NextPoints.Count);
                Assert.Equal(2, (viewModel.PlanObjects[7] as WallViewModel).End.NextPoints.Count);
                Assert.Equal(2, (viewModel.PlanObjects[9] as WallViewModel).Begin.NextPoints.Count);
                Assert.Equal(2, (viewModel.PlanObjects[9] as WallViewModel).End.NextPoints.Count);
                Assert.IsType(typeof(RoomViewModel), viewModel.PlanObjects[10]);

                var room = viewModel.PlanObjects[10] as RoomViewModel;
                Assert.NotNull(room.Current.Points);
                Assert.Equal(5, room.Current.Points.Count);
            }
        }

        /// <summary>
        /// Test the no delete point of the plan.
        /// </summary>
        [Fact]
        public void WithMoveButSamePointAndJonction()
        {
            using (new LocatorContext())
            {
                var viewModel = Locator.Locate<PlanViewModel>(null);
                viewModel.Init();
                viewModel.LoadPlanMessage(new Message.LoadPlanMessage { Plan = new Plan() });

                viewModel.AddWall(0, 0, 100, 100);

                viewModel.AddWall(100, 100, 100, 100);

                Assert.Equal(3, viewModel.PlanObjects.Count);
                Assert.IsType(typeof(WallViewModel), viewModel.PlanObjects[0]);
                Assert.IsType(typeof(PointViewModel), viewModel.PlanObjects[1]);
                Assert.IsType(typeof(PointViewModel), viewModel.PlanObjects[2]);
                Assert.Equal(0, (viewModel.PlanObjects[1] as PointViewModel).X);
                Assert.Equal(100, (viewModel.PlanObjects[2] as PointViewModel).X);
            }
        }
    }
}
